<?php
namespace app\extensions\lib\ta_shushu;
use app\exception\ApiException;
use app\extensions\lib\push\BasePush;
use app\model\Cate;
use FileConsumer;
use support\Log;
use ThinkingDataAnalytics;
use ThinkingDataException;

/**
 * Class Log
 * @package support
 *
 * @method  void user_set($level, $distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_setOnce($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_add($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_append($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_uniq_append($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_unset($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void user_del($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void track($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void track_first($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void track_update($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 * @method  void track_overwrite($distinct_id, $account_id, $properties,$event_name, $event_id, $is_add)
 */
class Shushu
{
    protected $cate_id;
    protected $appid;
    protected $token;
    public $event_table;
    public $user_table;
    protected $logbus_data_dir;
    protected $header = ['Content-Type: application/x-www-form-urlencoded'];
    private $uuid = false;

    public function __construct($cate_id,$uuid = false){
        try{
            $cate = Cate::getInfo($cate_id);
            $this->cate_id = $cate_id;
            $this->appid = $cate['ss_appid'] ?? '';
            $this->token = $cate['ss_token'] ?? '';
            $this->event_table = $cate['ss_event_table'] ?? '';
            $this->user_table = $cate['ss_user_table'] ?? '';
            $this->logbus_data_dir = env('LOG_PATH').'/ss/app_'.$this->appid;
            $this->uuid = $uuid;
        }catch (\Exception $e){
            //异常处理
            Log::channel('shushu')->error("创建数数对象失败".$e->getMessage().$e->getFile().$e->getLine());
        }
    }

    public function getEventId($start_date,$end_date,$conditionStr=''){
        $conditionStr && $conditionStr = ' and '.$conditionStr;
        $sql = "select \"#account_id\" as udid, request_id  from ta.{$this->event_table} where \"\$part_date\" BETWEEN '{$start_date}' AND '{$end_date}' $conditionStr";
        $result = $this->querySql($sql);
        $result = $this->shushuDataToArray($result);
        return $result;
    }

    public function querySql($sql,$pageSize='',$token=''){//查询数据
        $token = $token ?:$this->token;
        if(empty($token) or empty($this->event_table)) return false;
        $url = env('SHUSHU_URL').'querySql/?token='.$token;
        $params = ['sql' => $sql,'format' => 'json'];
        if($pageSize){
            $params['pageSize'] = $pageSize;
        }
        $result = curl($url, $params,1,$this->header,[],[],false);
        return $result;
    }
    public function shushuDataToArray($result){//将数数的数据转为数组
        $result = preg_split("/((\r?\n)|(\r\n?))/", $result); //切割每一行数据
        foreach ($result as $key => $value) {//去掉空值
            if(empty($value)) unset($result[$key]);
        }
        $num_data = count($result) - 1;
        if($num_data <= 0){
            return [];
        }

        $result_new = [];

        foreach($result as $kline => $line){//遍历每一行数据
            $line = json_decode($line,true);
            if(empty($line)) continue;
            if($kline == 0){//头部信息
                $dataKey = $line['data']['headers'];
            }else{
                $data = array_combine($dataKey,$line);//组装成key => value
                array_push($result_new, $data);
            }
        }

        unset($result);

        return $result_new;
    }

    public function pushLog($method,$distinct_id, $account_id, $properties,$event_name='', $event_id='',$is_add=true){
        $ta = null;
        $params = func_get_args();
        $status = false;
        try{
            $params = func_get_args();
            $ta = $this->add(...$params);
            Log::channel('shushu')->info('shushu-add::'.json_encode($params));
            $status = true;
        }catch (ThinkingDataException $e){
            Log::channel('shushu')->warning($e->getMessage());
        }catch(\Throwable $e){
            //dump($e->getTraceAsString());
            Log::channel('shushu')->error($e->getMessage().':'.json_encode($params));
        }

        $ta && $ta->close();
        return $status;
    }

    private  function add($method,$distinct_id, $account_id, $properties,$event_name='', $event_id='',$is_add=true){
        if(!$method){
            throw new ThinkingDataException("diy properties must be an array.");
        }

        $params = func_get_args();
        if(!is_array($properties) or empty($properties)){
            throw new ThinkingDataException("diy properties must be an array.");
        }
        list($log_name,$is_event) = $this->checkInfo($method,$event_name);
        $params[3] = $properties = $this->formatProperties($properties);
        $ta = new ThinkingDataAnalytics(new FileConsumer($this->logbus_data_dir."/log_".$log_name."/"),$this->uuid);
        if(!method_exists($ta,$method)){
            throw new ThinkingDataException("method_exists:no:{$method}");
        }
        $newParams = [$distinct_id,$account_id];
        if($is_event){
            $newParams[] = $event_name;
            $event_id && $newParams[] = $event_id;
            $properties = BasePush::shushDefaultData($event_name,$properties,$is_add);//默认数据
        }
        $newParams[] = $properties;
        //dump($method,$newParams);
        $ta->{$method}(...$newParams);
        $ta->flush();
        return $ta;
    }


    public function formatProperties($properties){
        /*foreach ($properties as $key => $value) {//属性值不能为null，将null转为空值
            if(is_null($value)) $properties[$key] = "";

            if($value === '0.00') $value = '0';

            if(!in_array($key, ["sdk_bind_type","role_level","server_id","tf_package_id","tf_game_id","tf_cate_id"])){
                $properties[$key] = (string) $value;
            }
        }

        if(isset($properties['is_sandbox'])){
            if(in_array($this->appid, ['ffe0ac8594074d3980e03ea1f9777850','d37b6341c9724e59afea4c603b8d8dbf'])){
                //宙斯的改is_sandbox类型
                $properties['is_sandbox'] = (int)$properties['is_sandbox'];
            }
        }*/
        return $properties;
    }

    private function checkInfo($method,$event_name)
    {
        $log_name = '';
        $is_event = true;
        if(strpos($method,'user_')!==false){
            $log_name =  $method;
            $is_event = false;
        }else{
            $log_name =  $event_name;
        }
        return [$log_name,$is_event];
    }

    public function __call($method, $args)
    {
        array_unshift($args,$method);
        if(strpos($method,'user_')!==false || strpos($method,'track')!==false){
            return $this->pushLog(...$args);
        }

    }


}
